/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Web
 * @{
 *
 * @brief 提供注入对象和执行JavaScript代码的API接口。
 * @since 11
 */
/**
 * @file native_interface_arkweb.h
 *
 * @brief 声明API接口供开发者使用注入对象和执行JavaScript代码等功能。
 * @kit ArkWeb
 * @include <web/native_interface_arkweb.h>
 * @library libohweb.so
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
#ifndef NATIVE_INTERFACE_ARKWEB_H
#define NATIVE_INTERFACE_ARKWEB_H

#include <stdbool.h>
#include <stdint.h>

#include "arkweb_error_code.h"
#include "arkweb_type.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @brief 定义执行JavaScript代码后返回结果的回调函数的类型。
*
* @since 11
*/
typedef void (*NativeArkWeb_OnJavaScriptCallback)(const char*);

/**
* @brief 定义注入对象的回调函数的类型。
*
* @since 11
*/
typedef char* (*NativeArkWeb_OnJavaScriptProxyCallback)(const char** argv, int32_t argc);

/**
* @brief 定义Web组件可用时的回调函数的类型。
*
* @since 11
*/
typedef void (*NativeArkWeb_OnValidCallback)(const char*);

/**
* @brief 定义Web组件销毁时的回调函数的类型。
*
* @since 11
*/
typedef void (*NativeArkWeb_OnDestroyCallback)(const char*);

/**
 * @brief 定义保存cookie的回调函数的类型。
 *
 * @param errorCode {@link ARKWEB_SUCCESS} 保存cookie成功。
 *                  {@link ARKWEB_COOKIE_MANAGER_INITIALIZE_FAILED} CookieManager初始化失败。
 *                  {@link ARKWEB_COOKIE_SAVE_FAILED} 保存cookie失败。
 * @since 20
 */
typedef void (*OH_ArkWeb_OnCookieSaveCallback)(ArkWeb_ErrorCode errorCode);

/**
* @brief 页面首屏加载预测信息，主要包括首屏相似度预测值，首屏加载耗时预测值，预测错误码，应用需根据此信息来决策是否启用无白屏加载插帧方案。
*
* @since 20
*/
typedef struct {
    /** 无白屏加载的异常错误码，见ArkWeb_BlanklessErrorCode定义。 */
    ArkWeb_BlanklessErrorCode errCode;
    /** 首屏相似度，根据历史加载首屏内容计算相似度，范围为0~1.0，1.0表示完全一致，数值越接近1，相似度越高。
     * 该值存在滞后性，本地加载的相似性将在下次加载时才可反映。建议当相似度较低时，应用不启用无白屏加载插帧方案。 */
    double similarity;
    /** 根据历史加载首屏耗时预测本次加载耗时，单位ms，取值范围需大于0。 */
    int32_t loadingTime;
} ArkWeb_BlanklessInfo;

/**
 * @brief ArkWeb内核版本，请参考[M114内核在OpenHarmony6.0系统上的适配指导](https://gitcode.com/openharmony-tpc/chromium_src/blob/132_trunk/web/ReleaseNote/CompatibleWithLegacyWebEngine.md)。
 *
 * @since 20
 */
typedef enum {
    /** 系统默认内核，OpenHarmony 6.0版本默认为M132。 */
    SYSTEM_DEFAULT = 0,

    /** OpenHarmony 6.0版本的遗留内核。开发者可选择此遗留内核，若系统版本上不存在此内核则设置无效。 */
    ARKWEB_M114 = 1,

    /** OpenHarmony 6.0版本的常青内核，M132为此版本的默认内核。若系统版本上不存在此内核则设置无效。 */
    ARKWEB_M132 = 2,

    /** 常青内核，系统的最新内核。开发者可选择在每个系统版本上都使用最新的内核，OpenHarmony 6.0及之后所有系统版本都生效。 */
    ARKWEB_EVERGREEN = 99999,
} ArkWebEngineVersion;

/**
 * @brief 在当前显示页面的环境下，加载并执行一段JavaScript代码。
 *
 * @param webTag Web组件的名称。
 * @param jsCode 一段JavaScript的代码脚本。
 * @param callback 代码执行完后通知开发者结果的回调函数。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
void OH_NativeArkWeb_RunJavaScript(const char* webTag, const char* jsCode, NativeArkWeb_OnJavaScriptCallback callback);

/**
 * @brief 注册对象及函数名称列表。
 *
 * @param webTag Web组件的名称。
 * @param objName 注入对象的名称。
 * @param methodList 注入函数列表的名称。
 * @param callback 注入的回调函数。
 * @param size 注入的回调函数的个数。
 * @param needRefresh 是否需要刷新页面。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
void OH_NativeArkWeb_RegisterJavaScriptProxy(const char* webTag, const char* objName, const char** methodList,
    NativeArkWeb_OnJavaScriptProxyCallback* callback, int32_t size, bool needRefresh);

/**
 * @brief 删除已注册的对象及其下的回调函数。
 *
 * @param webTag Web组件的名称。
 * @param objName 注入对象的名称。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
void OH_NativeArkWeb_UnregisterJavaScriptProxy(const char* webTag, const char* objName);

/**
 * @brief 设置对象可注册时的回调函数。
 *
 * @param webTag Web组件的名称。
 * @param callback 对象可注册时的回调函数。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
void OH_NativeArkWeb_SetJavaScriptProxyValidCallback(const char* webTag, NativeArkWeb_OnValidCallback callback);

/**
 * @brief 获取已注册的对象可注册时的回调函数。
 *
 * @param webTag Web组件的名称。
 * @return return 已注册的对象可注册时的回调函数。如果未设置由参数webTag指定的有效回调函数，则将返回空指针。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
NativeArkWeb_OnValidCallback OH_NativeArkWeb_GetJavaScriptProxyValidCallback(const char* webTag);

/**
 * @brief 设置组件销毁时的回调函数。
 *
 * @param webTag Web组件的名称。
 * @param callback 组件销毁时的回调函数。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
void OH_NativeArkWeb_SetDestroyCallback(const char* webTag, NativeArkWeb_OnDestroyCallback callback);

/**
 * @brief 获取已注册的组件销毁时的回调函数。
 *
 * @param webTag Web组件的名称。
 * @return return 已注册的组件销毁时的回调函数。如果未设置由参数webTag指定的销毁回调函数，则将返回空指针。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 11
 */
NativeArkWeb_OnDestroyCallback OH_NativeArkWeb_GetDestroyCallback(const char* webTag);

/**
 * @brief 加载数据或URL，此函数应在主线程中调用。
 *
 * @param webTag Web组件的名称。
 * @param data "Base64"或"URL"编码的字符串，不能为空。
 * @param mimeType 媒体类型，例如"text/html"，不能为空。
 * @param encoding 编码类型，例如"UTF-8"，不能为空。
 * @param baseUrl 指定的URL路径("http"/"https"/"data"协议),
 *                由Web组件分配给window.origin。
 * @param historyUrl 历史URL，当它不为空时，可以通过历史记录来管理，实现前进和后退功能。
 * @return LoadData 错误码。
 *         {@link ARKWEB_SUCCESS} 加载数据成功。
 *         {@link ARKWEB_INVALID_PARAM} 必填参数未指定或参数类型不正确或参数校验失败。
 *         {@link ARKWEB_INIT_ERROR} 初始化失败，根据传入的"webTag"找不到有效的Web组件。
 *         {@link ARKWEB_LIBRARY_OPEN_FAILURE} 打开动态链接库失败。
 *         {@link ARKWEB_LIBRARY_SYMBOL_NOT_FOUND} 动态链接库中未找到所需的符号。
 *
 * @syscap SystemCapability.Web.Webview.Core
 * @since 15
 */
ArkWeb_ErrorCode OH_NativeArkWeb_LoadData(const char* webTag,
                                          const char* data,
                                          const char* mimeType,
                                          const char* encoding,
                                          const char* baseUrl,
                                          const char* historyUrl);

/**
 * @brief 注册一个包含回调方法的 JavaScript 对象，这些方法可带有返回值。该对象将被注入到当前页面的所有frame中，
 *        包括所有的 iframe，并且可以通过在 ArkWeb_ProxyObjectWithResult 中指定的名称进行访问。
 *        该对象只会在下一次加载或重新加载页面后在 JavaScript 中生效。这些方法将在 ArkWeb 的工作线程中执行。
 *
 * @param webTag Web组件名称。
 * @param proxyObject 注册的对象。
 * @param permission json格式字符串，默认值为空。该字符串用来配置JSBridge的权限限制，可以配置对象和方法级别。
 *
 * @since 20
 */
void OH_NativeArkWeb_RegisterAsyncThreadJavaScriptProxy(const char* webTag,
    const ArkWeb_ProxyObjectWithResult* proxyObject, const char* permission);

/**
 * @brief 将当前可通过CookieManager API访问的所有Cookie持久化到磁盘。
 *        如果要在非UI线程中使用此接口，则需要先使用OH_ArkWeb_GetNativeAPI初始化CookieManager接口。
 * @return SaveCookieSync错误码。
 *         {@link ARKWEB_SUCCESS} 保存cookie成功。
 *         {@link ARKWEB_COOKIE_SAVE_FAILED} 保存cookie失败。
 *         {@link ARKWEB_COOKIE_MANAGER_INITIALIZE_FAILED} CookieManager初始化失败。
 *         {@link ARKWEB_COOKIE_MANAGER_NOT_INITIALIZED} 在非UI线程中，不允许在不初始化CookieManager接口的情况下调用该接口。
 *                                                       请先使用OH_ArkWeb_GetNativeAPI初始化CookieManager接口。
 * @since 20
 */
ArkWeb_ErrorCode OH_ArkWebCookieManager_SaveCookieSync();

/**
 * @brief 将当前可通过CookieManager API访问的所有Cookie持久化到磁盘。
 *        在不初始化CookieManager接口的情况下，此接口将在UI线程上自动执行。
 * @param callback 保存cookie完成后执行该回调。
 * @since 20
 */
void OH_ArkWebCookieManager_SaveCookieAsync(OH_ArkWeb_OnCookieSaveCallback callback);

/**
 * @brief 获取页面首屏加载预测信息（详细说明见BlanklessInfo），并开始本次加载过渡帧生成，应用根据此信息确定是否需要启用无白屏加载。
 *        必须与OH_NativeArkWeb_SetBlanklessLoadingWithKey接口配套使用，并且必须在触发加载页面的接口之前调用。需在WebViewController与Web组件绑定后才能使用。
 *        设备行为差异：该接口在Phone中可正常调用，在其他设备类型中返回801错误码。
 *        持久缓存容量：默认大小为30MB（约30页），可以通过接口OH_NativeArkWeb_SetBlanklessLoadingCacheCapacity设置缓存容量，具体见该接口说明。
 *        超过容量时根据LRU（Least Recently Used，淘汰不常用缓存的策略）机制更新缓存。自动清理超过7天的持久缓存数据，缓存清除后第三次加载页面开始有优化效果。
 *        如果发现相似度（即ArkWeb_BlanklessInfo中的similarity）极低，请检查key值是否正确传递。
 *        调用本接口后，会启用页面加载快照检测及生成过渡帧计算，产生一定资源开销。
 *        启用无白屏加载的页面会带来一定的资源开销，开销的大小与Web组件的分辨率相关。假设分辨率的宽度和高度分别为：w, h。
 *        页面在打开阶段会增加峰值内存，增加量约为12*w*h B。页面打开后，内存会被回收，不影响稳态内存。增加固态应用缓存的大小，每个页面增加的缓存约w*h/10 B，缓存位于应用缓存的位置。
 *
 * @param webTag Web组件名称。
 * @param key 唯一标识本页面的key值。合法取值范围：非空，长度不超过2048个字符。设置非法值时不生效。
 * @return 页面首屏加载预测信息，主要包括首屏相似度预测值，首屏加载耗时预测值，应用需根据此信息来决策是否启用无白屏加载插帧。
 * @permission ohos.permission.INTERNET和ohos.permission.GET_NETWORK_INFO
 * @since 20
 */
ArkWeb_BlanklessInfo OH_NativeArkWeb_GetBlanklessInfoWithKey(const char* webTag, const char* key);

/**
 * @brief 设置无白屏加载是否启用。本接口必须与OH_NativeArkWeb_GetBlanklessInfoWithKey接口配套使用。
 * 必须与OH_NativeArkWeb_GetBlanklessInfoWithKey接口配套。需在触发页面加载的接口之后调用。其他约束同OH_NativeArkWeb_GetBlanklessInfoWithKey。
 * 页面的加载必须在调用本套接口的组件中进行。
 * 当相似度较低时，系统将判定为跳变过大，启用插帧会失败。
 *
 * @param webTag Web组件名称。
 * @param key 唯一标识本页面的key值。必须与OH_NativeArkWeb_GetBlanklessInfoWithKey接口的key值相同。
 *            默认值：无。合法取值范围：非空，长度不超过2048个字符。非法值设置行为：返回错误码。
 * @param isStarted 是否启用开始插帧，true：启用，false：不启用。默认值：false。
 * @return 返回接口调用是否成功，具体见ArkWeb_BlanklessErrorCode定义。
 * @permission ohos.permission.INTERNET和ohos.permission.GET_NETWORK_INFO
 * @since 20
 */
ArkWeb_BlanklessErrorCode OH_NativeArkWeb_SetBlanklessLoadingWithKey(const char* webTag,
                                                                     const char* key,
                                                                     bool isStarted);

/**
 * @brief 清除指定key值页面无白屏优化缓存，本接口只清除缓存。
 *        在小程序或Web应用场景中，当页面加载时内容变化显著，可能会出现一次明显的跳变。若对此跳变有所顾虑，可使用该接口清除页面缓存。
 *        清除之后的页面，需在第三次加载页面时才会产生优化效果。
 *
 * @param key 清除Blankless优化方案页面的key值列表，key值为OH_NativeArkWeb_GetBlanklessInfoWithKey中指定过的。默认值：所有Blankless优化方案缓存的页面key列表。
 *            合法取值范围：长度不超过2048，key列表长度<=100。key和加载页面时输入给ArkWeb的相同。非法值设置行为：key长度超过2048时该key不生效；
 *            长度超过100时，取前100个；当为NULL时，使用默认值。
 * @param size keys数组的大小。默认值：0。合法取值范围：0~100。取值超过100时，keys数组取前100个。非法值设置行为：0。
 * @since 20
 */
void OH_NativeArkWeb_ClearBlanklessLoadingCache(const char* key[], uint32_t size);

/**
 * @brief 设置无白屏加载方案的持久化缓存容量，返回实际生效值。默认缓存容量为30MB，最大值为100MB。
 *        当实际缓存超过容量时，将采用淘汰不常用的过渡帧的方式清理。
 *
 * @param capacity 设置持久化缓存设置，单位MB，最大设置不超过100MB。默认值：30MB。合法取值范围：0~100，当设置为0时，无缓存空间，
 *                 则功能全局不开启。非法值设置行为：小于0时生效值为0，大于100时生效值为100。
 * @return 返回实际生效的容量值，范围0~100。小于0时生效值为0，大于100时生效值为100。
 * @since 20
 */
uint32_t OH_NativeArkWeb_SetBlanklessLoadingCacheCapacity(uint32_t capacity);

/**
 * @brief 设置ArkWeb内核版本。若系统不支持指定版本，则设置无效。
 *        该接口为全局静态方法，须在调用initializeWebEngine前执行，若已加载任何Web组件，则该设置无效。
 *        在OpenHarmony 6.0及以后，使用遗留内核时，部分ArkWeb接口不会生效，参考[M114内核在OpenHarmony6.0系统上的适配指导](https://gitcode.com/openharmony-tpc/chromium_src/blob/132_trunk/web/ReleaseNote/CompatibleWithLegacyWebEngine.md)。
 *
 * @param ArkWebEngineVersion ArkWeb内核版本。
 * @since 20
 */
void OH_NativeArkWeb_SetActiveWebEngineVersion(ArkWebEngineVersion webEngineVersion);

/**
 * @brief 获取当前使用的ArkWeb内核版本。
 *
 * @return 返回由{@link ArkWebEngineVersion}枚举所定义的当前使用的ArkWeb内核版本。
 * @since 20
 */
ArkWebEngineVersion OH_NativeArkWeb_GetActiveWebEngineVersion();

/**
 * @brief 判断应用所使用ArkWeb内核是否是常青内核。
 *
 * @return 表示当前应用所使用内核是否为常青内核。true表示当前应用所使用内核是常青内核，false表示当前应用所使用内核不是常青内核。
 * @since 21
 */
bool OH_NativeArkWeb_IsActiveWebEngineEvergreen();

#ifdef __cplusplus
};
#endif
#endif // NATIVE_INTERFACE_ARKWEB_H
